package com.zhny.aiot.bighouse.quilt.plugin;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableMap;
import com.zhny.aiot.bighouse.quilt.plugin.model.AdjustableParam;
import com.zhny.aiot.bighouse.quilt.plugin.model.QuiltStoreEntry;
import com.zhny.aiot.plugin.ICenterFacilities;
import com.zhny.aiot.plugin.IDeviceFactory;
import com.zhny.aiot.plugin.core.model.IRequestMessage;
import com.zhny.aiot.plugin.core.utils.MessageUtils;
import com.zhny.aiot.plugin.modbus.ModemEngine;
import com.zhny.aiot.plugin.modbus.device.ModemConfig;
import com.zhny.aiot.plugin.modbus.device.ModemDevice;
import com.zhny.aiot.plugin.modbus.device.modbus.ModbusCommandParam;
import com.zhny.aiot.plugin.modbus.handler.model.ModemRequestMessage;
import com.zhny.aiot.plugin.modbus.handler.model.ModemResponseMessage;
import com.zhny.aiot.plugin.model.DeviceEntity;
import com.zhny.aiot.plugin.model.MessageEntry;
import com.zhny.aiot.plugin.model.MessageType;
import com.zhny.aiot.plugin.model.TaskEntity;
import org.pf4j.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;

public class QuiltDevice extends ModemDevice<QuiltStoreEntry> {
    private static final Logger logger=LoggerFactory.getLogger (QuiltDevice.class);
    private final Map<String, ModbusCommandParam> CommandOperations;

    public QuiltDevice(ModemEngine engine, IDeviceFactory<ModemConfig> factory, ICenterFacilities centerFacilities, DeviceEntity entity) {
        super (engine, factory, centerFacilities, entity);

        CommandOperations=new ImmutableMap.Builder<String, ModbusCommandParam> ()
                .put ("open", ModbusCommandParam.valueOf ((short) 6, 10, 0x0065))
                .put ("close", ModbusCommandParam.valueOf ((short) 6, 10, 0x0066))
                .put ("stop", ModbusCommandParam.valueOf ((short) 6, 10, 0x0068))
                .put ("value", ModbusCommandParam.valueOf ((short) 6, 10, 0x0064))
                .put ("query", ModbusCommandParam.valueOf ((short) 3, 3, 1))

                .build ();
    }

    @Override
    public void onDecoder(ModemResponseMessage modemResponseMessage) {
        MessageEntry entry=MessageUtils.createMessageEntry (this.getId ());
        entry.setType (MessageType.RESULT);
        entry.getProperties ().put ("gprs", ((ModemConfig) this.getConfig ()).getGprsNo ());
        entry.getProperties ().put ("address", ((ModemConfig) this.getConfig ()).getAddress ());

        int isRecord=modemResponseMessage.getData ().readByte ();
        int status=modemResponseMessage.getData ().readByte ();
        String value="";
        if(modemResponseMessage.getFunction () == 0x06) {
            value=onStatusConvert (status);
        }else if(modemResponseMessage.getFunction () == 0x03) {
            value=onStatusConvert (status);
        }else {
            entry.setType (MessageType.ERROR);
            nofity (entry);
        }
        QuiltStoreEntry storeEntry=new QuiltStoreEntry ();
        logger.info ("卷被机：{} 获取值:{}", this.getDeviceEntity ().getName (), value);
        storeEntry.setStatus (value);
        entry.setData (storeEntry);
        nofity (entry);
        saveReal (storeEntry);
    }

//    private String onQueryConvert(int status) {
//        return status == 0 ? "错误" :
//                status == 1 ? "全开" :
//                        status == 2 ? "全关" :
//                                status == 3 ? "半开":"异常";
//    }

    private String onStatusConvert(int status) {
        return status == 101 ? "全开" :
                status == 102 ? "全关" :
                        status == 103 ? "学习" :
                                status == 104 ? "停止" : String.valueOf (status);
    }

    @Override
    protected IRequestMessage getCommand(TaskEntity taskEntity) {
        MessageEntry entry=MessageUtils.createMessageEntry (this.getId ());
        entry.getProperties ().put ("task_name", taskEntity.getMethodName ());
        entry.setType (MessageType.OPERATION);
        ModbusCommandParam command=CommandOperations.get (taskEntity.getMethodName ());
        if(command == null) {
            logger.info (String.format ("factory[%s] no found func[%s]", getTypeId (), taskEntity.getMethodName ()));
            entry.setType (MessageType.ERROR);
            this.nofity (entry);
            return null;
        }
        logger.info ("quilt task func:{},param:{}",taskEntity.getMethodName (),taskEntity.getParams ());
        if(taskEntity.getMethodName ().equals ("value")){
           if(!StringUtils.isNullOrEmpty (taskEntity.getParams ())) {
               AdjustableParam param=null;
               ObjectMapper mapper = new ObjectMapper();
               mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
               try{
                   param = mapper.readValue (taskEntity.getParams (),AdjustableParam.class);
               }catch (Exception e){
                   logger.error ("Parse param error !");
                   return  null;
               }
               command = ModbusCommandParam.valueOf ((short)6,10, param.getValue ());
           }else {
               logger.info (String.format ("factory[%s]  set adjust value command [%s] error param value:[%s]", getTypeId (), taskEntity.getMethodName (),taskEntity.getParams ()));
               entry.setType (MessageType.ERROR);
               this.nofity (entry);
               return null;
           }
        }

        return new ModemRequestMessage (
                Integer.valueOf (this.getConfig ().getAddress ()),
                command.getOper (),
                command.getRegAdress (),
                command.getDataSize ()
        );
    }

    @Override
    protected void disposable() {

    }
}
